# -*- coding: utf-8 -*-
"""
Created on Mon Jan  7 21:52:08 2019

@author: william

Email: hua_yan_tsn@163.com
"""

import tensorflow as tf
import numpy as np
# 常量区域

h = 3
regular_word_vector_dim = 3
weight_matrices = np.zeros((h * regular_word_vector_dim))
weight_matrices = np.zeros([])
def convolution(filter, originalMatrix):
    """
    进行的是池化卷积操作: question: 池化和卷积的区别是什么？
    :param filter: 线性的滤波的因子， 维度为 h * d, tensor对象
    :param originalMatrix: 原矩阵 维度为 s * d, tensor对象
    :return: 卷积之后的结果维度为 s + h - 1
    """
    [h, d] = filter.shape
    s = originalMatrix.shape[0]
    zero_matrics = tf.zeros(shape=[h-1, d], dtype=filter.dtype)
    generatedMatrix = tf.concat([zero_matrics, originalMatrix, zero_matrics], axis=0)
    answer = tf.zeros(shape=[s + h -1, 1], dtype=filter.dtype)
    for i in range(0, s + h -1):
        operationMatrix = tf.slice(generatedMatrix, [i, 0], [i + h - 1, d])
        answer[i] = tf.reduce_sum(operationMatrix * filter)
    print("after filtering:")
    print(answer.eval(session=tf.Session().close()))
    return answer

def featureMap(convolutionOut, bias):
    """
    :param convolutionOut:卷积操作的结果向量
    :param bias: 偏置项
    :return: 使用ReLU函数作为activation function的操作结果
    """
    return tf.nn.relu(convolutionOut + bias)

def initialVp(vectors):
    """
    使用 vectors的均值去初始化sentiment level
    :param vectors: 由memory module生成的一个情感词向量集合
    :return: Vp
    """
    return tf.reduce_sum(vectors, axis=0)

def getSimilarity(vectors, Vp):
    """
    TODO 次数很可能出现错误，需要仔细检查维度的特征
    获得vectors中的每行分量与Vp的相似度关联
    :param vectors: sentiment vectors的集合
    :param Vp: sentiment level
    :return: similarity的一个vector|tensor
    """
    innerPart = tf.matmul(tf.reverse(Vp), vectors)
    l2_normalization = tf.sqrt(tf.reduce_sum(innerPart * innerPart, axis=1))
    temp = tf.exp(innerPart / l2_normalization)
    sum = tf.reduce_sum(temp)
    similarity = temp / sum
    return similarity

def getSentimenLevel(similarities, vectors):
    """
    获得sentiment level vector Vo
    :param similarities: 所有sentiment vector的平均值和各分量之间的相似度矩阵
    :param vectors: sentiment vectors
    :return: sentiment level vectors
    """
    l2_normalization = tf.sqrt(tf.reduce_sum(similarities))
    Vo = tf.zeros(similarities.shape, dtype=similarities.dtype)
    for i in range(0, vectors.shape[0]):
        Vo = Vo + similarities[0]/l2_normalization * vectors[0]
    return Vo

def main():
    cv = convolution(1,1)
    sentiment_embeddins = featureMap(cv, 100)
    Vp = initialVp(sentiment_embeddins)
    similarity = getSimilarity(sentiment_embeddins, Vp)
    sentiment_level = tf.zeros(similarity.shape)
    for i in range(sentiment_level.shape[0]): # k passes
        sentiment_level = sentiment_level + getSentimenLevel(similarity, sentiment_embeddins)